<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Chapter 10. Zend_Db</title>
<link rel="stylesheet" href="dbstyle.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<link rel="start" href="index.html" title="Programmer's Reference Guide">
<link rel="up" href="index.html" title="Programmer's Reference Guide">
<link rel="prev" href="zend.date.additional.html" title="9.7. Working examples">
<link rel="next" href="zend.db.statement.html" title="10.2. Zend_Db_Statement">
<link rel="chapter" href="introduction.html" title="Chapter 1. Introduction to Zend Framework">
<link rel="chapter" href="zend.acl.html" title="Chapter 2. Zend_Acl">
<link rel="chapter" href="zend.auth.html" title="Chapter 3. Zend_Auth">
<link rel="chapter" href="zend.cache.html" title="Chapter 4. Zend_Cache">
<link rel="chapter" href="zend.config.html" title="Chapter 5. Zend_Config">
<link rel="chapter" href="zend.console.getopt.html" title="Chapter 6. Zend_Console_Getopt">
<link rel="chapter" href="zend.controller.html" title="Chapter 7. Zend_Controller">
<link rel="chapter" href="zend.currency.html" title="Chapter 8. Zend_Currency">
<link rel="chapter" href="zend.date.html" title="Chapter 9. Zend_Date">
<link rel="chapter" href="zend.db.html" title="Chapter 10. Zend_Db">
<link rel="chapter" href="zend.debug.html" title="Chapter 11. Zend_Debug">
<link rel="chapter" href="zend.dojo.html" title="Chapter 12. Zend_Dojo">
<link rel="chapter" href="zend.dom.html" title="Chapter 13. Zend_Dom">
<link rel="chapter" href="zend.exception.html" title="Chapter 14. Zend_Exception">
<link rel="chapter" href="zend.feed.html" title="Chapter 15. Zend_Feed">
<link rel="chapter" href="zend.filter.html" title="Chapter 16. Zend_Filter">
<link rel="chapter" href="zend.form.html" title="Chapter 17. Zend_Form">
<link rel="chapter" href="zend.gdata.html" title="Chapter 18. Zend_Gdata">
<link rel="chapter" href="zend.http.html" title="Chapter 19. Zend_Http">
<link rel="chapter" href="zend.infocard.html" title="Chapter 20. Zend_InfoCard">
<link rel="chapter" href="zend.json.html" title="Chapter 21. Zend_Json">
<link rel="chapter" href="zend.layout.html" title="Chapter 22. Zend_Layout">
<link rel="chapter" href="zend.ldap.html" title="Chapter 23. Zend_Ldap">
<link rel="chapter" href="zend.loader.html" title="Chapter 24. Zend_Loader">
<link rel="chapter" href="zend.locale.html" title="Chapter 25. Zend_Locale">
<link rel="chapter" href="zend.log.html" title="Chapter 26. Zend_Log">
<link rel="chapter" href="zend.mail.html" title="Chapter 27. Zend_Mail">
<link rel="chapter" href="zend.measure.html" title="Chapter 28. Zend_Measure">
<link rel="chapter" href="zend.memory.html" title="Chapter 29. Zend_Memory">
<link rel="chapter" href="zend.mime.html" title="Chapter 30. Zend_Mime">
<link rel="chapter" href="zend.openid.html" title="Chapter 31. Zend_OpenId">
<link rel="chapter" href="zend.paginator.html" title="Chapter 32. Zend_Paginator">
<link rel="chapter" href="zend.pdf.html" title="Chapter 33. Zend_Pdf">
<link rel="chapter" href="zend.registry.html" title="Chapter 34. Zend_Registry">
<link rel="chapter" href="zend.rest.html" title="Chapter 35. Zend_Rest">
<link rel="chapter" href="zend.search.lucene.html" title="Chapter 36. Zend_Search_Lucene">
<link rel="chapter" href="zend.server.html" title="Chapter 37. Zend_Server">
<link rel="chapter" href="zend.service.html" title="Chapter 38. Zend_Service">
<link rel="chapter" href="zend.session.html" title="Chapter 39. Zend_Session">
<link rel="chapter" href="zend.soap.html" title="Chapter 40. Zend_Soap">
<link rel="chapter" href="zend.test.html" title="Chapter 41. Zend_Test">
<link rel="chapter" href="zend.text.html" title="Chapter 42. Zend_Text">
<link rel="chapter" href="zend.timesync.html" title="Chapter 43. Zend_TimeSync">
<link rel="chapter" href="zend.translate.html" title="Chapter 44. Zend_Translate">
<link rel="chapter" href="zend.uri.html" title="Chapter 45. Zend_Uri">
<link rel="chapter" href="zend.validate.html" title="Chapter 46. Zend_Validate">
<link rel="chapter" href="zend.version.html" title="Chapter 47. Zend_Version">
<link rel="chapter" href="zend.view.html" title="Chapter 48. Zend_View">
<link rel="chapter" href="zend.xmlrpc.html" title="Chapter 49. Zend_XmlRpc">
<link rel="appendix" href="requirements.html" title="Appendix A. Zend Framework Requirements">
<link rel="appendix" href="coding-standard.html" title="Appendix B. Zend Framework Coding Standard for PHP">
<link rel="appendix" href="copyrights.html" title="Appendix C. Copyright Information">
<link rel="index" href="the.index.html" title="Index">
<link rel="section" href="zend.db.html#zend.db.adapter" title="10.1. Zend_Db_Adapter">
<link rel="section" href="zend.db.statement.html" title="10.2. Zend_Db_Statement">
<link rel="section" href="zend.db.profiler.html" title="10.3. Zend_Db_Profiler">
<link rel="section" href="zend.db.select.html" title="10.4. Zend_Db_Select">
<link rel="section" href="zend.db.table.html" title="10.5. Zend_Db_Table">
<link rel="section" href="zend.db.table.row.html" title="10.6. Zend_Db_Table_Row">
<link rel="section" href="zend.db.table.rowset.html" title="10.7. Zend_Db_Table_Rowset">
<link rel="section" href="zend.db.table.relationships.html" title="10.8. Zend_Db_Table Relationships">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader"><table width="100%" summary="Navigation header">
<tr><th colspan="3" align="center">Chapter 10. Zend_Db</th></tr>
<tr>
<td width="20%" align="left">
<a accesskey="p" href="zend.date.additional.html">Prev</a> </td>
<th width="60%" align="center"> </th>
<td width="20%" align="right"> <a accesskey="n" href="zend.db.statement.html">Next</a>
</td>
</tr>
</table></div>
<div class="chapter" lang="en">
<div class="titlepage"><div><div><h2 class="title">
<a name="zend.db"></a>Chapter 10. Zend_Db</h2></div></div></div>
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
<dt><span class="sect1"><a href="zend.db.html#zend.db.adapter">10.1. Zend_Db_Adapter</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="zend.db.html#zend.db.adapter.connecting">10.1.1. Connecting to a Database using an Adapter</a></span></dt>
<dd><dl>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.connecting.constructor">10.1.1.1. Using a Zend_Db Adapter Constructor</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.connecting.factory">10.1.1.2. Using the Zend_Db Factory</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.connecting.factory-config">10.1.1.3. Using Zend_Config with the Zend_Db Factory</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.connecting.parameters">10.1.1.4. Adapter Parameters</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.connecting.getconnection">10.1.1.5. Managing Lazy Connections</a></span></dt>
</dl></dd>
<dt><span class="sect2"><a href="zend.db.html#zend.db.adapter.example-database">10.1.2. The example database</a></span></dt>
<dt><span class="sect2"><a href="zend.db.html#zend.db.adapter.select">10.1.3. Reading Query Results</a></span></dt>
<dd><dl>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.select.fetchall">10.1.3.1. Fetching a Complete Result Set</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.select.fetch-mode">10.1.3.2. Changing the Fetch Mode</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.select.fetchassoc">10.1.3.3. Fetching a Result Set as an Associative Array</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.select.fetchcol">10.1.3.4. Fetching a Single Column from a Result Set</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.select.fetchpairs">10.1.3.5. Fetching Key-Value Pairs from a Result Set</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.select.fetchrow">10.1.3.6. Fetching a Single Row from a Result Set</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.select.fetchone">10.1.3.7. Fetching a Single Scalar from a Result Set</a></span></dt>
</dl></dd>
<dt><span class="sect2"><a href="zend.db.html#zend.db.adapter.write">10.1.4. Writing Changes to the Database</a></span></dt>
<dd><dl>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.write.insert">10.1.4.1. Inserting Data</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.write.lastinsertid">10.1.4.2. Retrieving a Generated Value</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.write.update">10.1.4.3. Updating Data</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.write.delete">10.1.4.4. Deleting Data</a></span></dt>
</dl></dd>
<dt><span class="sect2"><a href="zend.db.html#zend.db.adapter.quoting">10.1.5. Quoting Values and Identifiers</a></span></dt>
<dd><dl>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.quoting.quote">10.1.5.1. Using <code class="code">quote()</code></a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.quoting.quote-into">10.1.5.2. Using <code class="code">quoteInto()</code></a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.quoting.quote-identifier">10.1.5.3. Using <code class="code">quoteIdentifier()</code></a></span></dt>
</dl></dd>
<dt><span class="sect2"><a href="zend.db.html#zend.db.adapter.transactions">10.1.6. Controlling Database Transactions</a></span></dt>
<dt><span class="sect2"><a href="zend.db.html#zend.db.adapter.list-describe">10.1.7. Listing and Describing Tables</a></span></dt>
<dt><span class="sect2"><a href="zend.db.html#zend.db.adapter.closing">10.1.8. Closing a Connection</a></span></dt>
<dt><span class="sect2"><a href="zend.db.html#zend.db.adapter.other-statements">10.1.9. Running Other Database Statements</a></span></dt>
<dt><span class="sect2"><a href="zend.db.html#zend.db.adapter.adapter-notes">10.1.10. Notes on Specific Adapters</a></span></dt>
<dd><dl>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.adapter-notes.ibm-db2">10.1.10.1. IBM DB2</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.adapter-notes.mysqli">10.1.10.2. MySQLi</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.adapter-notes.oracle">10.1.10.3. Oracle</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.adapter-notes.pdo-ibm">10.1.10.4. PDO for IBM DB2 and Informix Dynamic Server (IDS)</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.adapter-notes.pdo-mssql">10.1.10.5. PDO Microsoft SQL Server</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.adapter-notes.pdo-mysql">10.1.10.6. PDO MySQL</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.adapter-notes.pdo-oci">10.1.10.7. PDO Oracle</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.adapter-notes.pdo-pgsql">10.1.10.8. PDO PostgreSQL</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.adapter-notes.pdo-sqlite">10.1.10.9. PDO SQLite</a></span></dt>
<dt><span class="sect3"><a href="zend.db.html#zend.db.adapter.adapter-notes.firebird">10.1.10.10. Firebird/Interbase</a></span></dt>
</dl></dd>
</dl></dd>
<dt><span class="sect1"><a href="zend.db.statement.html">10.2. Zend_Db_Statement</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="zend.db.statement.html#zend.db.statement.creating">10.2.1. Creating a Statement</a></span></dt>
<dt><span class="sect2"><a href="zend.db.statement.html#zend.db.statement.executing">10.2.2. Executing a Statement</a></span></dt>
<dt><span class="sect2"><a href="zend.db.statement.html#zend.db.statement.fetching">10.2.3. Fetching Results from a <code class="code">SELECT</code> Statement</a></span></dt>
<dd><dl>
<dt><span class="sect3"><a href="zend.db.statement.html#zend.db.statement.fetching.fetch">10.2.3.1. Fetching a Single Row from a Result Set</a></span></dt>
<dt><span class="sect3"><a href="zend.db.statement.html#zend.db.statement.fetching.fetchall">10.2.3.2. Fetching a Complete Result Set</a></span></dt>
<dt><span class="sect3"><a href="zend.db.statement.html#zend.db.statement.fetching.fetch-mode">10.2.3.3. Changing the Fetch Mode</a></span></dt>
<dt><span class="sect3"><a href="zend.db.statement.html#zend.db.statement.fetching.fetchcolumn">10.2.3.4. Fetching a Single Column from a Result Set</a></span></dt>
<dt><span class="sect3"><a href="zend.db.statement.html#zend.db.statement.fetching.fetchobject">10.2.3.5. Fetching a Row as an Object</a></span></dt>
</dl></dd>
</dl></dd>
<dt><span class="sect1"><a href="zend.db.profiler.html">10.3. Zend_Db_Profiler</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="zend.db.profiler.html#zend.db.profiler.introduction">10.3.1. Introduction</a></span></dt>
<dt><span class="sect2"><a href="zend.db.profiler.html#zend.db.profiler.using">10.3.2. Using the Profiler</a></span></dt>
<dt><span class="sect2"><a href="zend.db.profiler.html#zend.db.profiler.advanced">10.3.3. Advanced Profiler Usage</a></span></dt>
<dd><dl>
<dt><span class="sect3"><a href="zend.db.profiler.html#zend.db.profiler.advanced.filtertime">10.3.3.1. Filter by query elapsed time</a></span></dt>
<dt><span class="sect3"><a href="zend.db.profiler.html#zend.db.profiler.advanced.filtertype">10.3.3.2. Filter by query type</a></span></dt>
<dt><span class="sect3"><a href="zend.db.profiler.html#zend.db.profiler.advanced.getbytype">10.3.3.3. Retrieve profiles by query type</a></span></dt>
</dl></dd>
</dl></dd>
<dt><span class="sect1"><a href="zend.db.select.html">10.4. Zend_Db_Select</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="zend.db.select.html#zend.db.select.introduction">10.4.1. Overview of the Select Object</a></span></dt>
<dt><span class="sect2"><a href="zend.db.select.html#zend.db.select.creating">10.4.2. Creating a Select Object</a></span></dt>
<dt><span class="sect2"><a href="zend.db.select.html#zend.db.select.building">10.4.3. Building Select queries</a></span></dt>
<dd><dl>
<dt><span class="sect3"><a href="zend.db.select.html#zend.db.select.building.from">10.4.3.1. Adding a FROM clause</a></span></dt>
<dt><span class="sect3"><a href="zend.db.select.html#zend.db.select.building.columns">10.4.3.2. Adding Columns</a></span></dt>
<dt><span class="sect3"><a href="zend.db.select.html#zend.db.select.building.columns-expr">10.4.3.3. Adding Expression Columns</a></span></dt>
<dt><span class="sect3"><a href="zend.db.select.html#zend.db.select.building.columns-atomic">10.4.3.4. Adding columns to an existing FROM or JOIN table</a></span></dt>
<dt><span class="sect3"><a href="zend.db.select.html#zend.db.select.building.join">10.4.3.5. Adding Another Table to the Query with JOIN</a></span></dt>
<dt><span class="sect3"><a href="zend.db.select.html#zend.db.select.building.where">10.4.3.6. Adding a WHERE Clause</a></span></dt>
<dt><span class="sect3"><a href="zend.db.select.html#zend.db.select.building.group">10.4.3.7. Adding a GROUP BY Clause</a></span></dt>
<dt><span class="sect3"><a href="zend.db.select.html#zend.db.select.building.having">10.4.3.8. Adding a HAVING Clause</a></span></dt>
<dt><span class="sect3"><a href="zend.db.select.html#zend.db.select.building.order">10.4.3.9. Adding an ORDER BY Clause</a></span></dt>
<dt><span class="sect3"><a href="zend.db.select.html#zend.db.select.building.limit">10.4.3.10. Adding a LIMIT Clause</a></span></dt>
<dt><span class="sect3"><a href="zend.db.select.html#zend.db.select.building.distinct">10.4.3.11. Adding the DISTINCT Query Modifier</a></span></dt>
<dt><span class="sect3"><a href="zend.db.select.html#zend.db.select.building.for-update">10.4.3.12. Adding the FOR UPDATE Query Modifier</a></span></dt>
</dl></dd>
<dt><span class="sect2"><a href="zend.db.select.html#zend.db.select.execute">10.4.4. Executing Select Queries</a></span></dt>
<dd><dl>
<dt><span class="sect3"><a href="zend.db.select.html#zend.db.select.execute.query-adapter">10.4.4.1. Executing Select Queries from the Db Adapter</a></span></dt>
<dt><span class="sect3"><a href="zend.db.select.html#zend.db.select.execute.query-select">10.4.4.2. Executing Select Queries from the Object</a></span></dt>
<dt><span class="sect3"><a href="zend.db.select.html#zend.db.select.execute.tostring">10.4.4.3. Converting a Select Object to a SQL String</a></span></dt>
</dl></dd>
<dt><span class="sect2"><a href="zend.db.select.html#zend.db.select.other">10.4.5. Other methods</a></span></dt>
<dd><dl>
<dt><span class="sect3"><a href="zend.db.select.html#zend.db.select.other.get-part">10.4.5.1. Retrieving Parts of the Select Object</a></span></dt>
<dt><span class="sect3"><a href="zend.db.select.html#zend.db.select.other.reset">10.4.5.2. Resetting Parts of the Select Object</a></span></dt>
</dl></dd>
</dl></dd>
<dt><span class="sect1"><a href="zend.db.table.html">10.5. Zend_Db_Table</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="zend.db.table.html#zend.db.table.introduction">10.5.1. Introduction to Table Class</a></span></dt>
<dt><span class="sect2"><a href="zend.db.table.html#zend.db.table.defining">10.5.2. Defining a Table Class</a></span></dt>
<dd><dl>
<dt><span class="sect3"><a href="zend.db.table.html#zend.db.table.defining.table-schema">10.5.2.1. Defining the Table Name and Schema</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.html#zend.db.table.defining.primary-key">10.5.2.2. Defining the Table Primary Key</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.html#zend.db.table.defining.setup">10.5.2.3. Overriding Table Setup Methods</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.html#zend.db.table.initialization">10.5.2.4. Table initialization</a></span></dt>
</dl></dd>
<dt><span class="sect2"><a href="zend.db.table.html#zend.db.table.constructing">10.5.3. Creating an Instance of a Table</a></span></dt>
<dd><dl>
<dt><span class="sect3"><a href="zend.db.table.html#zend.db.table.constructing.adapter">10.5.3.1. Specifying a Database Adapter</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.html#zend.db.table.constructing.default-adapter">10.5.3.2. Setting a Default Database Adapter</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.html#zend.db.table.constructing.registry">10.5.3.3. Storing a Database Adapter in the Registry</a></span></dt>
</dl></dd>
<dt><span class="sect2"><a href="zend.db.table.html#zend.db.table.insert">10.5.4. Inserting Rows to a Table</a></span></dt>
<dd><dl>
<dt><span class="sect3"><a href="zend.db.table.html#zend.db.table.insert.key-auto">10.5.4.1. Using a Table with an Auto-incrementing Key</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.html#zend.db.table.insert.key-sequence">10.5.4.2. Using a Table with a Sequence</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.html#zend.db.table.insert.key-natural">10.5.4.3. Using a Table with a Natural Key</a></span></dt>
</dl></dd>
<dt><span class="sect2"><a href="zend.db.table.html#zend.db.table.update">10.5.5. Updating Rows in a Table</a></span></dt>
<dt><span class="sect2"><a href="zend.db.table.html#zend.db.table.delete">10.5.6. Deleting Rows from a Table</a></span></dt>
<dt><span class="sect2"><a href="zend.db.table.html#zend.db.table.find">10.5.7. Finding Rows by Primary Key</a></span></dt>
<dt><span class="sect2"><a href="zend.db.table.html#zend.db.table.fetch-all">10.5.8. Querying for a Set of Rows</a></span></dt>
<dd><dl>
<dt><span class="sect3"><a href="zend.db.table.html#zend.db.table.fetch-all.select">10.5.8.1. Select API</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.html#zend.db.table.fetch-all.usage">10.5.8.2. Fetching a rowset</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.html#zend.db.table.advanced.usage">10.5.8.3. Advanced usage</a></span></dt>
</dl></dd>
<dt><span class="sect2"><a href="zend.db.table.html#zend.db.table.fetch-row">10.5.9. Querying for a Single Row</a></span></dt>
<dt><span class="sect2"><a href="zend.db.table.html#zend.db.table.info">10.5.10. Retrieving Table Metadata Information</a></span></dt>
<dt><span class="sect2"><a href="zend.db.table.html#zend.db.table.metadata.caching">10.5.11. Caching Table Metadata</a></span></dt>
<dt><span class="sect2"><a href="zend.db.table.html#zend.db.table.extending">10.5.12. Customizing and Extending a Table Class</a></span></dt>
<dd><dl>
<dt><span class="sect3"><a href="zend.db.table.html#zend.db.table.extending.row-rowset">10.5.12.1. Using Custom Row or Rowset Classes</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.html#zend.db.table.extending.insert-update">10.5.12.2. Defining Custom Logic for Insert, Update, and Delete</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.html#zend.db.table.extending.finders">10.5.12.3. Define Custom Search Methods in Zend_Db_Table</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.html#zend.db.table.extending.inflection">10.5.12.4. Define Inflection in Zend_Db_Table</a></span></dt>
</dl></dd>
</dl></dd>
<dt><span class="sect1"><a href="zend.db.table.row.html">10.6. Zend_Db_Table_Row</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="zend.db.table.row.html#zend.db.table.row.introduction">10.6.1. Introduction</a></span></dt>
<dt><span class="sect2"><a href="zend.db.table.row.html#zend.db.table.row.read">10.6.2. Fetching a Row</a></span></dt>
<dd><dl>
<dt><span class="sect3"><a href="zend.db.table.row.html#zend.db.table.row.read.get">10.6.2.1. Reading column values from a row</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.row.html#zend.db.table.row.read.to-array">10.6.2.2. Retrieving Row Data as an Array</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.row.html#zend.db.table.row.read.relationships">10.6.2.3. Fetching data from related tables</a></span></dt>
</dl></dd>
<dt><span class="sect2"><a href="zend.db.table.row.html#zend.db.table.row.write">10.6.3. Writing rows to the database</a></span></dt>
<dd><dl>
<dt><span class="sect3"><a href="zend.db.table.row.html#zend.db.table.row.write.set">10.6.3.1. Changing column values in a row</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.row.html#zend.db.table.row.write.insert">10.6.3.2. Inserting a new row</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.row.html#zend.db.table.row.write.set-from-array">10.6.3.3. Changing values in multiple columns</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.row.html#zend.db.table.row.write.delete">10.6.3.4. Deleting a row</a></span></dt>
</dl></dd>
<dt><span class="sect2"><a href="zend.db.table.row.html#zend.db.table.row.serialize">10.6.4. Serializing and unserializing rows</a></span></dt>
<dd><dl>
<dt><span class="sect3"><a href="zend.db.table.row.html#zend.db.table.row.serialize.serializing">10.6.4.1. Serializing a Row</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.row.html#zend.db.table.row.serialize.unserializing">10.6.4.2. Unserializing Row Data</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.row.html#zend.db.table.row.serialize.set-table">10.6.4.3. Reactivating a Row as Live Data</a></span></dt>
</dl></dd>
<dt><span class="sect2"><a href="zend.db.table.row.html#zend.db.table.row.extending">10.6.5. Extending the Row class</a></span></dt>
<dd><dl>
<dt><span class="sect3"><a href="zend.db.table.row.html#zend.db.table.row.extending.overriding">10.6.5.1. Row initialization</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.row.html#zend.db.table.row.extending.insert-update">10.6.5.2. Defining Custom Logic for Insert, Update, and Delete in Zend_Db_Table_Row</a></span></dt>
<dt><span class="sect3"><a href="zend.db.table.row.html#zend.db.table.row.extending.inflection">10.6.5.3. Define Inflection in Zend_Db_Table_Row</a></span></dt>
</dl></dd>
</dl></dd>
<dt><span class="sect1"><a href="zend.db.table.rowset.html">10.7. Zend_Db_Table_Rowset</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="zend.db.table.rowset.html#zend.db.table.rowset.introduction">10.7.1. Introduction</a></span></dt>
<dt><span class="sect2"><a href="zend.db.table.rowset.html#zend.db.table.rowset.fetch">10.7.2. Fetching a Rowset</a></span></dt>
<dt><span class="sect2"><a href="zend.db.table.rowset.html#zend.db.table.rowset.rows">10.7.3. Retrieving Rows from a Rowset</a></span></dt>
<dt><span class="sect2"><a href="zend.db.table.rowset.html#zend.db.table.rowset.to-array">10.7.4. Retrieving a Rowset as an Array</a></span></dt>
<dt><span class="sect2"><a href="zend.db.table.rowset.html#zend.db.table.rowset.serialize">10.7.5. Serializing and Unserializing a Rowset</a></span></dt>
<dt><span class="sect2"><a href="zend.db.table.rowset.html#zend.db.table.rowset.extending">10.7.6. Extending the Rowset class</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="zend.db.table.relationships.html">10.8. Zend_Db_Table Relationships</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="zend.db.table.relationships.html#zend.db.table.relationships.introduction">10.8.1. Introduction</a></span></dt>
<dt><span class="sect2"><a href="zend.db.table.relationships.html#zend.db.table.relationships.defining">10.8.2. Defining Relationships</a></span></dt>
<dt><span class="sect2"><a href="zend.db.table.relationships.html#zend.db.table.relationships.fetching.dependent">10.8.3. Fetching a Dependent Rowset</a></span></dt>
<dt><span class="sect2"><a href="zend.db.table.relationships.html#zend.db.table.relationships.fetching.parent">10.8.4. Fetching a Parent Row</a></span></dt>
<dt><span class="sect2"><a href="zend.db.table.relationships.html#zend.db.table.relationships.fetching.many-to-many">10.8.5. Fetching a Rowset via a Many-to-many Relationship</a></span></dt>
<dt><span class="sect2"><a href="zend.db.table.relationships.html#zend.db.table.relationships.cascading">10.8.6. Cascading Write Operations</a></span></dt>
<dd><dl><dt><span class="sect3"><a href="zend.db.table.relationships.html#zend.db.table.relationships.cascading.notes">10.8.6.1. Notes Regarding Cascading Operations</a></span></dt></dl></dd>
</dl></dd>
</dl>
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="zend.db.adapter"></a>10.1. Zend_Db_Adapter</h2></div></div></div>
<p>
        Zend_Db and its related classes provide a simple SQL database interface
        for Zend Framework.  The Zend_Db_Adapter is the basic class you use to
        connect your PHP application to an RDBMS.  There is a different Adapter
        class for each brand of RDBMS.
    </p>
<p>
        The Zend_Db Adapters create a bridge from the vendor-specific PHP
        extensions to a common interface, to help you write PHP applications
        once and deploy with multiple brands of RDBMS with very little effort.
    </p>
<p>
        The interface of the Adapter class is similar to the interface of the
        <a href="http://www.php.net/pdo" target="_top">PHP Data Objects</a> extension.
        Zend_Db provides Adapter classes to PDO drivers for the following RDBMS
        brands:
    </p>
<div class="itemizedlist"><ul type="disc">
<li><p>
                IBM DB2 and Informix Dynamic Server (IDS), using the
                <a href="http://www.php.net/pdo-ibm" target="_top">pdo_ibm</a> PHP extension
            </p></li>
<li><p>
                MySQL, using the <a href="http://www.php.net/pdo-mysql" target="_top">pdo_mysql</a> PHP extension
            </p></li>
<li><p>
                Microsoft SQL Server, using the <a href="http://www.php.net/pdo-mssql" target="_top">pdo_mssql</a> PHP
                extension
            </p></li>
<li><p>
                Oracle, using the <a href="http://www.php.net/pdo-oci" target="_top">pdo_oci</a> PHP extension
            </p></li>
<li><p>
                PostgreSQL, using the <a href="http://www.php.net/pdo-pgsql" target="_top">pdo_pgsql</a> PHP extension
            </p></li>
<li><p>
                SQLite, using the <a href="http://www.php.net/pdo-sqlite" target="_top">pdo_sqlite</a> PHP extension
            </p></li>
</ul></div>
<p>
        In addition, Zend_Db provides Adapter classes that utilize PHP database
        extensions for the following RDBMS brands:
    </p>
<div class="itemizedlist"><ul type="disc">
<li><p>
                MySQL, using the <a href="http://www.php.net/mysqli" target="_top">mysqli</a> PHP extension
            </p></li>
<li><p>
                Oracle, using the <a href="http://www.php.net/oci8" target="_top">oci8</a> PHP extension
            </p></li>
<li><p>
                IBM DB2, using the <a href="http://www.php.net/ibm_db2" target="_top">ibm_db2</a> PHP extension
            </p></li>
<li><p>
                Firebird/Interbase, using the <a href="http://www.php.net/ibase" target="_top">php_interbase</a> PHP extension
            </p></li>
</ul></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
            Each Zend_Db Adapter uses a PHP extension.  You must have the
            respective PHP extension enabled in your PHP environment to use a
            Zend_Db Adapter.  For example, if you use any of the PDO Zend_Db
            Adapters, you need to enable both the PDO extension and the
            PDO driver for the brand of RDBMS you use.
        </p></td></tr>
</table></div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="zend.db.adapter.connecting"></a>10.1.1. Connecting to a Database using an Adapter</h3></div></div></div>
<p>
            This section describes how to create an instance of a database Adapter.
            This corresponds to making a connection to your RDBMS server from your
            PHP application.
        </p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.connecting.constructor"></a>10.1.1.1. Using a Zend_Db Adapter Constructor</h4></div></div></div>
<p>
                You can create an instance of an Adapter using its constructor.
                An Adapter constructor takes one argument, which is an array
                of parameters used to declare the connection.
            </p>
<div class="example">
<a name="zend.db.adapter.connecting.constructor.example"></a><p class="title"><b>Example 10.1. Using an Adapter constructor</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
require_once 'Zend/Db/Adapter/Pdo/Mysql.php';

$db = new Zend_Db_Adapter_Pdo_Mysql(array(
    'host'     =&gt; '127.0.0.1',
    'username' =&gt; 'webuser',
    'password' =&gt; 'xxxxxxxx',
    'dbname'   =&gt; 'test'
));
                </pre></div>
</div>
<br class="example-break">
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.connecting.factory"></a>10.1.1.2. Using the Zend_Db Factory</h4></div></div></div>
<p>
                As an alternative to using an Adapter constructor directly, you
                can create an instance of an Adapter using the static method
                <code class="code">Zend_Db::factory()</code>.  This method dynamically loads
                the Adapter class file on demand, using
                <a href="zend.loader.html#zend.loader.load.class" title="24.1.2. Loading Classes">Zend_Loader::loadClass()</a>.
            </p>
<p>
                The first argument is a string that names the base name of the
                Adapter class.  For example the string 'Pdo_Mysql' corresponds
                to the class Zend_Db_Adapter_Pdo_Mysql.  The second argument is
                the same array of parameters you would have given to the
                Adapter constructor.
            </p>
<div class="example">
<a name="zend.db.adapter.connecting.factory.example"></a><p class="title"><b>Example 10.2. Using the Adapter factory method</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
require_once 'Zend/Db.php';

// Automatically load class Zend_Db_Adapter_Pdo_Mysql and create an instance of it.
$db = Zend_Db::factory('Pdo_Mysql', array(
    'host'     =&gt; '127.0.0.1',
    'username' =&gt; 'webuser',
    'password' =&gt; 'xxxxxxxx',
    'dbname'   =&gt; 'test'
));
                </pre></div>
</div>
<br class="example-break"><p>
                If you create your own class that extends
                Zend_Db_Adapter_Abstract, but you do not name your class with
                the "Zend_Db_Adapter" package prefix, you can use the
                <code class="code">factory()</code> method to load your Adapter if you
                specify the leading portion of the adapter class with the
                'adapterNamespace' key in the parameters array.
            </p>
<div class="example">
<a name="zend.db.adapter.connecting.factory.example2"></a><p class="title"><b>Example 10.3. Using the Adapter factory method for a custom adapter class</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
require_once 'Zend/Db.php';

// Automatically load class MyProject_Db_Adapter_Pdo_Mysql and create an instance of it.
$db = Zend_Db::factory('Pdo_Mysql', array(
    'host'             =&gt; '127.0.0.1',
    'username'         =&gt; 'webuser',
    'password'         =&gt; 'xxxxxxxx',
    'dbname'           =&gt; 'test',
    'adapterNamespace' =&gt; 'MyProject_Db_Adapter'
));
                </pre></div>
</div>
<br class="example-break">
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.connecting.factory-config"></a>10.1.1.3. Using Zend_Config with the Zend_Db Factory</h4></div></div></div>
<p>
                Optionally, you may specify either argument of the
                <code class="code">factory()</code> method as an object of type
                <a href="zend.config.html" title="Chapter 5. Zend_Config">Zend_Config</a>.
            </p>
<p>
                If the first argument is a config object, it is expected to
                contain a property named <code class="code">adapter</code>, containing the
                string naming the adapter class name base.  Optionally, the object
                may contain a property named <code class="code">params</code>, with
                subproperties corresponding to adapter parameter names.
                This is used only if the second argument of the
                <code class="code">factory()</code> method is absent.
            </p>
<div class="example">
<a name="zend.db.adapter.connecting.factory.example1"></a><p class="title"><b>Example 10.4. Using the Adapter factory method with a Zend_Config object</b></p>
<div class="example-contents">
<p>
                    In the example below, a Zend_Config object is created from
                    an array.  You can also load data from an external file,
                    for example with
                    <a href="zend.config.adapters.ini.html" title="5.3. Zend_Config_Ini">Zend_Config_Ini</a>
                    or <a href="zend.config.adapters.xml.html" title="5.4. Zend_Config_Xml">Zend_Config_Xml</a>.
                </p>
<pre class="programlisting">&lt;?php
require_once 'Zend/Config.php';
require_once 'Zend/Db.php';

$config = new Zend_Config(
    array(
        'database' =&gt; array(
            'adapter' =&gt; 'Mysqli',
            'params' =&gt; array(
                'dbname' =&gt; 'test',
                'username' =&gt; 'webuser',
                'password' =&gt; 'secret',
            )
        )
    )
);

$db = Zend_Db::factory($config-&gt;database);
                </pre>
</div>
</div>
<br class="example-break"><p>
                The second argument of the <code class="code">factory()</code> method may be
                an associative array containing entries corresponding to
                adapter parameters.  This argument is optional.  If the first
                argument is of type Zend_Config, it is assumed to contain all
                parameters, and the second argument is ignored.
            </p>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.connecting.parameters"></a>10.1.1.4. Adapter Parameters</h4></div></div></div>
<p>
                The list below explains common parameters recognized by Zend_Db Adapter classes.
            </p>
<div class="itemizedlist"><ul type="disc">
<li><p>
                        <span class="strong"><strong>host</strong></span>:
                        a string containing a hostname or IP address of the
                        database server.  If the database is running on the
                        same host as the PHP application, you may use
                        'localhost' or '127.0.0.1'.
                    </p></li>
<li><p>
                        <span class="strong"><strong>username</strong></span>:
                        account identifier for authenticating a connection to the
                        RDBMS server.
                    </p></li>
<li><p>
                        <span class="strong"><strong>password</strong></span>:
                        account password credential for authenticating a
                        connection to the RDBMS server.
                    </p></li>
<li><p>
                        <span class="strong"><strong>dbname</strong></span>:
                        database instance name on the RDBMS server.
                    </p></li>
<li><p>
                        <span class="strong"><strong>port</strong></span>:
                        some RDBMS servers can accept network connections on a
                        administrator-specified port number.  The port
                        parameter allow you to specify the port to which your
                        PHP application connects, to match the port configured
                        on the RDBMS server.
                    </p></li>
<li><p>
                        <span class="strong"><strong>options</strong></span>:
                        this parameter is an associative array of options
                        that are generic to all Zend_Db_Adapter classes.
                    </p></li>
<li><p>
                        <span class="strong"><strong>driver_options</strong></span>:
                        this parameter is an associative array of additional
                        options that are specific to a given database
                        extension.  One typical use of this parameter is to
                        set attributes of a PDO driver.
                    </p></li>
<li><p>
                        <span class="strong"><strong>adapterNamespace</strong></span>:
                        names the initial part of the class name for the
                        adapter, instead of 'Zend_Db_Adapter'.  Use this if
                        you need to use the <code class="code">factory()</code> method to
                        load a non-Zend database adapter class.
                    </p></li>
</ul></div>
<div class="example">
<a name="zend.db.adapter.connecting.parameters.example1"></a><p class="title"><b>Example 10.5. Passing the case-folding option to the factory</b></p>
<div class="example-contents">
<p>
                    You can specify this option by the constant
                    <code class="code">Zend_Db::CASE_FOLDING</code>.
                    This corresponds to the <code class="code">ATTR_CASE</code> attribute in
                    PDO and IBM DB2 database drivers, adjusting the case of
                    string keys in query result sets.  The option takes values
                    <code class="code">Zend_Db::CASE_NATURAL</code> (the default),
                    <code class="code">Zend_Db::CASE_UPPER</code>, and
                    <code class="code">Zend_Db::CASE_LOWER</code>.
                </p>
<pre class="programlisting">&lt;?php
$options = array(
    Zend_Db::CASE_FOLDING =&gt; Zend_Db::CASE_UPPER
);

$params = array(
    'host'           =&gt; '127.0.0.1',
    'username'       =&gt; 'webuser',
    'password'       =&gt; 'xxxxxxxx',
    'dbname'         =&gt; 'test',
    'options'        =&gt; $options
);

$db = Zend_Db::factory('Db2', $params);
                </pre>
</div>
</div>
<br class="example-break"><div class="example">
<a name="zend.db.adapter.connecting.parameters.example2"></a><p class="title"><b>Example 10.6. Passing the auto-quoting option to the factory</b></p>
<div class="example-contents">
<p>
                    You can specify this option by the constant
                    <code class="code">Zend_Db::AUTO_QUOTE_IDENTIFIERS</code>.  If the value
                    is <code class="code">true</code> (the default), identifiers like table
                    names, column names, and even aliases are delimited in all
                    SQL syntax generated by the Adapter object.  This makes it
                    simple to use identifiers that contain SQL keywords, or
                    special characters.  If the value is <code class="code">false</code>,
                    identifiers are not delimited automatically.  If you need
                    to delimit identifiers, you must do so yourself using the
                    <code class="code">quoteIdentifier()</code> method.
                </p>
<pre class="programlisting">&lt;?php
$options = array(
    Zend_Db::AUTO_QUOTE_IDENTIFIERS =&gt; false
);

$params = array(
    'host'           =&gt; '127.0.0.1',
    'username'       =&gt; 'webuser',
    'password'       =&gt; 'xxxxxxxx',
    'dbname'         =&gt; 'test',
    'options'        =&gt; $options
);

$db = Zend_Db::factory('Pdo_Mysql', $params);
                </pre>
</div>
</div>
<br class="example-break"><div class="example">
<a name="zend.db.adapter.connecting.parameters.example3"></a><p class="title"><b>Example 10.7. Passing PDO driver options to the factory</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$pdoParams = array(
    PDO::MYSQL_ATTR_USE_BUFFERED_QUERY =&gt; true
);

$params = array(
    'host'           =&gt; '127.0.0.1',
    'username'       =&gt; 'webuser',
    'password'       =&gt; 'xxxxxxxx',
    'dbname'         =&gt; 'test',
    'driver_options' =&gt; $pdoParams
);

$db = Zend_Db::factory('Pdo_Mysql', $params);

echo $db-&gt;getConnection()-&gt;getAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY);
                </pre></div>
</div>
<br class="example-break">
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.connecting.getconnection"></a>10.1.1.5. Managing Lazy Connections</h4></div></div></div>
<p>
                Creating an instance of an Adapter class does not immediately
                connect to the RDBMS server.  The Adapter saves the connection
                parameters, and makes the actual connection on demand, the
                first time you need to execute a query.  This ensures that
                creating an Adapter object is quick and inexpensive.  You can
                create an instance of an Adapter even if you are not certain
                that you need to run any database queries during the current
                request your application is serving.
            </p>
<p>
                If you need to force the Adapter to connect to the RDBMS, use
                the <code class="code">getConnection()</code> method.  This method returns
                an object for the connection as represented by the respective
                PHP database extension.  For example, if you use any of the
                Adapter classes for PDO drivers, then
                <code class="code">getConnection()</code> returns the PDO object, after
                initiating it as a live connection to the specific database.
            </p>
<p>
                It can be useful to force the connection if you want to catch
                any exceptions it throws as a result of invalid account
                credentials, or other failure to connect to the RDBMS server.
                These exceptions are not thrown until the connection is made,
                so it can help simplify your application code if you handle the
                exceptions in one place, instead of at the time of
                the first query against the database.
            </p>
<div class="example">
<a name="zend.db.adapter.connecting.getconnection.example"></a><p class="title"><b>Example 10.8. Handling connection exceptions</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
try {
    $db = Zend_Db::factory('Pdo_Mysql', $parameters);
    $db-&gt;getConnection();
} catch (Zend_Db_Adapter_Exception $e) {
    // perhaps a failed login credential, or perhaps the RDBMS is not running
} catch (Zend_Exception $e) {
    // perhaps factory() failed to load the specified Adapter class
}
                </pre></div>
</div>
<br class="example-break">
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="zend.db.adapter.example-database"></a>10.1.2. The example database</h3></div></div></div>
<p>
            In the documentation for Zend_Db classes, we use a set of simple
            tables to illustrate usage of the classes and methods.  These
            example tables could store information for tracking bugs in a
            software development project.  The database contains four tables:
        </p>
<div class="itemizedlist"><ul type="disc">
<li><p>
                    <span class="strong"><strong>accounts</strong></span> stores
                    information about each user of the bug-tracking database.
                </p></li>
<li><p>
                    <span class="strong"><strong>products</strong></span> stores
                    information about each product for which a bug can be
                    logged.
                </p></li>
<li><p>
                    <span class="strong"><strong>bugs</strong></span> stores information
                    about bugs, including that current state of the bug, the
                    person who reported the bug, the person who is assigned to
                    fix the bug, and the person who is assigned to verify the
                    fix.
                </p></li>
<li><p>
                    <span class="strong"><strong>bugs_products</strong></span> stores a
                    relationship between bugs and products.  This implements a
                    many-to-many relationship, because a given bug may be
                    relevant to multiple products, and of course a given
                    product can have multiple bugs.
                </p></li>
</ul></div>
<p>
            The following SQL data definition language pseudocode describes the
            tables in this example database.  These example tables are used
            extensively by the automated unit tests for Zend_Db.
        </p>
<pre class="programlisting">
CREATE TABLE accounts (
  account_name      VARCHAR(100) NOT NULL PRIMARY KEY
);

CREATE TABLE products (
  product_id        INTEGER NOT NULL PRIMARY KEY,
  product_name      VARCHAR(100)
);

CREATE TABLE bugs (
  bug_id            INTEGER NOT NULL PRIMARY KEY,
  bug_description   VARCHAR(100),
  bug_status        VARCHAR(20),
  reported_by       VARCHAR(100) REFERENCES accounts(account_name),
  assigned_to       VARCHAR(100) REFERENCES accounts(account_name),
  verified_by       VARCHAR(100) REFERENCES accounts(account_name)
);

CREATE TABLE bugs_products (
  bug_id            INTEGER NOT NULL REFERENCES bugs,
  product_id        INTEGER NOT NULL REFERENCES products,
  PRIMARY KEY       (bug_id, product_id)
);
        </pre>
<p>
            Also notice that the <code class="code">bugs</code> table contains multiple
            foreign key references to the <code class="code">accounts</code> table.
            Each of these foreign keys may reference a different row in the
            <code class="code">accounts</code> table for a given bug.
        </p>
<p>
            The diagram below illustrates the physical data model of the
            example database.
        </p>
<p>
            <img src="figures/zend.db.adapter.example-database.png" align="middle">
        </p>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="zend.db.adapter.select"></a>10.1.3. Reading Query Results</h3></div></div></div>
<p>
            This section describes methods of the Adapter class with which you
            can run SELECT queries and retrieve the query results.
        </p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.select.fetchall"></a>10.1.3.1. Fetching a Complete Result Set</h4></div></div></div>
<p>
                You can run a SQL SELECT query and retrieve its results in one
                step using the <code class="code">fetchAll()</code> method.
            </p>
<p>
                The first argument to this method is a string containing a
                SELECT statement.  Alternatively, the first argument can be an
                object of class <a href="zend.db.select.html" title="10.4. Zend_Db_Select">Zend_Db_Select</a>.
                The Adapter automatically converts this object to a string
                representation of the SELECT statement.
            </p>
<p>
                The second argument to <code class="code">fetchAll()</code> is an array of
                values to substitute for parameter placeholders in the SQL
                statement.
            </p>
<div class="example">
<a name="zend.db.adapter.select.fetchall.example"></a><p class="title"><b>Example 10.9. Using fetchAll()</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$sql = 'SELECT * FROM bugs WHERE bug_id = ?';

$result = $db-&gt;fetchAll($sql, 2);
                </pre></div>
</div>
<br class="example-break">
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.select.fetch-mode"></a>10.1.3.2. Changing the Fetch Mode</h4></div></div></div>
<p>
                By default, <code class="code">fetchAll()</code> returns an array of
                rows, each of which is an associative array.  The keys of the
                associative array are the columns or column aliases named in
                the select query.
            </p>
<p>
                You can specify a different style of fetching results using the
                <code class="code">setFetchMode()</code> method.  The modes supported are
                identified by constants:
            </p>
<div class="itemizedlist"><ul type="disc">
<li>
<p>
                        <span class="strong"><strong>Zend_Db::FETCH_ASSOC</strong></span>:
                        return data in an array of associative arrays.
                        The array keys are column names, as strings.
                        This is the default fetch mode for Zend_Db_Adapter classes.
                    </p>
<p>
                        Note that if your select-list contains more than one
                        column with the same name, for example if they are from
                        two different tables in a JOIN, there can be only one
                        entry in the associative array for a given name.
                        If you use the FETCH_ASSOC mode, you should specify
                        column aliases in your SELECT query to ensure that the
                        names result in unique array keys.
                    </p>
<p>
                        By default, these strings are returned as they are
                        returned by the database driver.  This is typically the
                        spelling of the column in the RDBMS server.  You can
                        specify the case for these strings, using the
                        <code class="code">Zend_Db::CASE_FOLDING</code> option.
                        Specify this when instantiating the Adapter.
                        See <a href="zend.db.html#zend.db.adapter.connecting.parameters.example1" title="Example 10.5. Passing the case-folding option to the factory">Example 10.5, “Passing the case-folding option to the factory”</a>.
                    </p>
</li>
<li><p>
                        <span class="strong"><strong>Zend_Db::FETCH_NUM</strong></span>:
                        return data in an array of arrays.  The arrays are
                        indexed by integers, corresponding to the position of
                        the respective field in the select-list of the query.
                    </p></li>
<li><p>
                        <span class="strong"><strong>Zend_Db::FETCH_BOTH</strong></span>:
                        return data in an array of arrays.  The array keys are
                        both strings as used in the FETCH_ASSOC mode, and
                        integers as used in the FETCH_NUM mode.  Note that the
                        number of elements in the array is double that which
                        would be in the array if you used either FETCH_ASSOC
                        or FETCH_NUM.
                    </p></li>
<li><p>
                        <span class="strong"><strong>Zend_Db::FETCH_COLUMN</strong></span>:
                        return data in an array of values.  The value in each array
                        is the value returned by one column of the result set.
                        By default, this is the first column, indexed by 0.
                    </p></li>
<li><p>
                        <span class="strong"><strong>Zend_Db::FETCH_OBJ</strong></span>:
                        return data in an array of objects.  The default class
                        is the PHP built-in class stdClass.  Columns of the
                        result set are available as public properties of the
                        object.
                    </p></li>
</ul></div>
<div class="example">
<a name="zend.db.adapter.select.fetch-mode.example"></a><p class="title"><b>Example 10.10. Using setFetchMode()</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$db-&gt;setFetchMode(Zend_Db::FETCH_OBJ);

$result = $db-&gt;fetchAll('SELECT * FROM bugs WHERE bug_id = ?', 2);

// $result is an array of objects
echo $result[0]-&gt;bug_description;
                </pre></div>
</div>
<br class="example-break">
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.select.fetchassoc"></a>10.1.3.3. Fetching a Result Set as an Associative Array</h4></div></div></div>
<p>
                The <code class="code">fetchAssoc()</code> method returns data in an array
                of associative arrays, regardless of what value you have set
                for the fetch mode.
            </p>
<div class="example">
<a name="zend.db.adapter.select.fetchassoc.example"></a><p class="title"><b>Example 10.11. Using fetchAssoc()</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$db-&gt;setFetchMode(Zend_Db::FETCH_OBJ);

$result = $db-&gt;fetchAssoc('SELECT * FROM bugs WHERE bug_id = ?', 2);

// $result is an array of associative arrays, in spite of the fetch mode
echo $result[0]['bug_description'];
                </pre></div>
</div>
<br class="example-break">
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.select.fetchcol"></a>10.1.3.4. Fetching a Single Column from a Result Set</h4></div></div></div>
<p>
                The <code class="code">fetchCol()</code> method returns data in an array
                of values, regardless of the value you have set for the fetch mode.
                This only returns the first column returned by the query.
                Any other columns returned by the query are discarded.
                If you need to return a column other than the first, see <a href="zend.db.statement.html#zend.db.statement.fetching.fetchcolumn" title="10.2.3.4. Fetching a Single Column from a Result Set">Section 10.2.3.4, “Fetching a Single Column from a Result Set”</a>.
            </p>
<div class="example">
<a name="zend.db.adapter.select.fetchcol.example"></a><p class="title"><b>Example 10.12. Using fetchCol()</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$db-&gt;setFetchMode(Zend_Db::FETCH_OBJ);

$result = $db-&gt;fetchCol('SELECT bug_description, bug_id FROM bugs WHERE bug_id = ?', 2);

// contains bug_description; bug_id is not returned
echo $result[0];
                </pre></div>
</div>
<br class="example-break">
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.select.fetchpairs"></a>10.1.3.5. Fetching Key-Value Pairs from a Result Set</h4></div></div></div>
<p>
                The <code class="code">fetchPairs()</code> method returns data in an array
                of key-value pairs, as an associative array with a single entry
                per row.  The key of this associative array is taken from the
                first column returned by the SELECT query.  The value is taken
                from the second column returned by the SELECT query.  Any other
                columns returned by the query are discarded.
            </p>
<p>
                You should design the SELECT query so that the first column
                returned has unique values.  If there are duplicates values in
                the first column, entries in the associative array will be
                overwritten.
            </p>
<div class="example">
<a name="zend.db.adapter.select.fetchpairs.example"></a><p class="title"><b>Example 10.13. Using fetchPairs()</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$db-&gt;setFetchMode(Zend_Db::FETCH_OBJ);

$result = $db-&gt;fetchPairs('SELECT bug_id, bug_status FROM bugs');

echo $result[2];
                </pre></div>
</div>
<br class="example-break">
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.select.fetchrow"></a>10.1.3.6. Fetching a Single Row from a Result Set</h4></div></div></div>
<p>
                The <code class="code">fetchRow()</code> method returns data using the
                current fetch mode, but it returns only the first row
                fetched from the result set.
            </p>
<div class="example">
<a name="zend.db.adapter.select.fetchrow.example"></a><p class="title"><b>Example 10.14. Using fetchRow()</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$db-&gt;setFetchMode(Zend_Db::FETCH_OBJ);

$result = $db-&gt;fetchRow('SELECT * FROM bugs WHERE bug_id = 2');

// note that $result is a single object, not an array of objects
echo $result-&gt;bug_description;
                </pre></div>
</div>
<br class="example-break">
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.select.fetchone"></a>10.1.3.7. Fetching a Single Scalar from a Result Set</h4></div></div></div>
<p>
                The <code class="code">fetchOne()</code> method is like a combination
                of <code class="code">fetchRow()</code> with <code class="code">fetchCol()</code>,
                in that it returns data only for the first row fetched from
                the result set, and it returns only the value of the first
                column in that row.  Therefore it returns only a single
                scalar value, not an array or an object.
            </p>
<div class="example">
<a name="zend.db.adapter.select.fetchone.example"></a><p class="title"><b>Example 10.15. Using fetchOne()</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$result = $db-&gt;fetchOne('SELECT bug_status FROM bugs WHERE bug_id = 2');

// this is a single string value
echo $result;
                </pre></div>
</div>
<br class="example-break">
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="zend.db.adapter.write"></a>10.1.4. Writing Changes to the Database</h3></div></div></div>
<p>
            You can use the Adapter class to write new data or change existing
            data in your database.  This section describes methods to do these
            operations.
        </p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.write.insert"></a>10.1.4.1. Inserting Data</h4></div></div></div>
<p>
                You can add new rows to a table in your database using the
                <code class="code">insert()</code> method.  The first argument is a string
                that names the table, and the second argument is an associative
                array, mapping column names to data values.
            </p>
<div class="example">
<a name="zend.db.adapter.write.insert.example"></a><p class="title"><b>Example 10.16. Inserting to a table</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$data = array(
    'created_on'      =&gt; '2007-03-22',
    'bug_description' =&gt; 'Something wrong',
    'bug_status'      =&gt; 'NEW'
);

$db-&gt;insert('bugs', $data);
                </pre></div>
</div>
<br class="example-break"><p>
                Columns you exclude from the array of data are not specified to
                the database.  Therefore, they follow the same rules that an
                SQL INSERT statement follows:  if the column has a DEFAULT
                clause, the column takes that value in the row created,
                otherwise the column is left in a NULL state.
            </p>
<p>
                By default, the values in your data array are inserted using
                parameters.  This reduces risk of some types of security
                issues.  You don't need to apply escaping or quoting to values
                in the data array.
            </p>
<p>
                You might need values in the data array to be treated as SQL
                expressions, in which case they should not be quoted.  By
                default, all data values passed as strings are treated as
                string literals.  To specify that the value is an SQL
                expression and therefore should not be quoted, pass the value
                in the data array as an object of type Zend_Db_Expr instead of
                a plain string.
            </p>
<div class="example">
<a name="zend.db.adapter.write.insert.example2"></a><p class="title"><b>Example 10.17. Inserting expressions to a table</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$data = array(
    'created_on'      =&gt; new Zend_Db_Expr('CURDATE()'),
    'bug_description' =&gt; 'Something wrong',
    'bug_status'      =&gt; 'NEW'
);

$db-&gt;insert('bugs', $data);
                </pre></div>
</div>
<br class="example-break">
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.write.lastinsertid"></a>10.1.4.2. Retrieving a Generated Value</h4></div></div></div>
<p>
                Some RDBMS brands support auto-incrementing primary keys.
                A table defined this way generates a primary key value
                automatically during an INSERT of a new row.  The return value
                of the <code class="code">insert()</code> method is <span class="emphasis"><em>not</em></span>
                the last inserted ID, because the table might not have an
                auto-incremented column.  Instead, the return value is the
                number of rows affected (usually 1).
            </p>
<p>
                If your table is defined with an auto-incrementing primary key,
                you can call the <code class="code">lastInsertId()</code> method after the
                insert.  This method returns the last value generated in the
                scope of the current database connection.
            </p>
<div class="example">
<a name="zend.db.adapter.write.lastinsertid.example-1"></a><p class="title"><b>Example 10.18. Using lastInsertId() for an auto-increment key</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$db-&gt;insert('bugs', $data);

// return the last value generated by an auto-increment column
$id = $db-&gt;lastInsertId();
                </pre></div>
</div>
<br class="example-break"><p>
                Some RDBMS brands support a sequence object, which generates
                unique values to serve as primary key values.  To support
                sequences, the <code class="code">lastInsertId()</code> method accepts two
                optional string arguments.  These arguments name the table and
                the column, assuming you have followed the convention that a
                sequence is named using the table and column names for which
                the sequence generates values, and a suffix "_seq".  This is
                based on the convention used by PostgreSQL when naming
                sequences for SERIAL columns.  For example, a table "bugs" with
                primary key column "bug_id" would use a sequence named
                "bugs_bug_id_seq".
            </p>
<div class="example">
<a name="zend.db.adapter.write.lastinsertid.example-2"></a><p class="title"><b>Example 10.19. Using lastInsertId() for a sequence</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$db-&gt;insert('bugs', $data);

// return the last value generated by sequence 'bugs_bug_id_seq'.
$id = $db-&gt;lastInsertId('bugs', 'bug_id');

// alternatively, return the last value generated by sequence 'bugs_seq'.
$id = $db-&gt;lastInsertId('bugs');
                </pre></div>
</div>
<br class="example-break"><p>
                If the name of your sequence object does not follow this naming
                convention, use the <code class="code">lastSequenceId()</code> method
                instead.  This method takes a single string argument, naming
                the sequence literally.
            </p>
<div class="example">
<a name="zend.db.adapter.write.lastinsertid.example-3"></a><p class="title"><b>Example 10.20. Using lastSequenceId()</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$db-&gt;insert('bugs', $data);

// return the last value generated by sequence 'bugs_id_gen'.
$id = $db-&gt;lastSequenceId('bugs_id_gen');
                </pre></div>
</div>
<br class="example-break"><p>
                For RDBMS brands that don't support sequences, including MySQL,
                Microsoft SQL Server, and SQLite, the arguments to the
                lastInsertId() method are ignored, and the value returned is the
                most recent value generated for any table by INSERT operations
                during the current connection.   For these RDBMS brands, the
                lastSequenceId() method always returns <code class="code">null</code>.
            </p>
<div class="note"><table border="0" summary='Note: Why not use "SELECT MAX(id) FROM table"?'>
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td>
<th align="left">Why not use "SELECT MAX(id) FROM table"?</th>
</tr>
<tr><td align="left" valign="top">
<p>
                    Sometimes this query returns the most recent primary key
                    value inserted into the table.  However, this technique
                    is not safe to use in an environment where multiple clients are
                    inserting records to the database.  It is possible, and
                    therefore is bound to happen eventually, that another
                    client inserts another row in the instant between the
                    insert performed by your client application and your query
                    for the MAX(id) value.  Thus the value returned does not
                    identify the row you inserted, it identifies the row
                    inserted by some other client.  There is no way to know
                    when this has happened.
                </p>
<p>
                    Using a strong transaction isolation mode such as
                    "repeatable read" can mitigate this risk, but some RDBMS
                    brands don't support the transaction isolation required for
                    this, or else your application may use a lower transaction
                    isolation mode by design.
                </p>
<p>
                    Furthermore, using an expression like "MAX(id)+1" to generate
                    a new value for a primary key is not safe, because two clients
                    could do this query simultaneously, and then both use the same
                    calculated value for their next INSERT operation.
                </p>
<p>
                    All RDBMS brands provide mechanisms to generate unique
                    values, and to return the last value generated.  These
                    mechanisms necessarily work outside of the scope of
                    transaction isolation, so there is no chance of two clients
                    generating the same value, and there is no chance that the
                    value generated by another client could be reported to your
                    client's connection as the last value generated.
                </p>
</td></tr>
</table></div>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.write.update"></a>10.1.4.3. Updating Data</h4></div></div></div>
<p>
                You can update rows in a database table using the
                <code class="code">update()</code> method of an Adapter.  This method takes
                three arguments:  the first is the name of the table; the
                second is an associative array mapping columns to change to new
                values to assign to these columns.
            </p>
<p>
                The values in the data array are treated as string literals.
                See <a href="zend.db.html#zend.db.adapter.write.insert" title="10.1.4.1. Inserting Data">Section 10.1.4.1, “Inserting Data”</a>
                for information on using SQL expressions in the data array.
            </p>
<p>
                The third argument is a string containing an SQL expression
                that is used as criteria for the rows to change.  The values
                and identifiers in this argument are not quoted or escaped.
                You are responsible for ensuring that any dynamic content is
                interpolated into this string safely.
                See <a href="zend.db.html#zend.db.adapter.quoting" title="10.1.5. Quoting Values and Identifiers">Section 10.1.5, “Quoting Values and Identifiers”</a>
                for methods to help you do this.
            </p>
<p>
                The return value is the number of rows affected by the update
                operation.
            </p>
<div class="example">
<a name="zend.db.adapter.write.update.example"></a><p class="title"><b>Example 10.21. Updating rows</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$data = array(
    'updated_on'      =&gt; '2007-03-23',
    'bug_status'      =&gt; 'FIXED'
);

$n = $db-&gt;update('bugs', $data, 'bug_id = 2');
                </pre></div>
</div>
<br class="example-break"><p>
                If you omit the third argument, then all rows in the database
                table are updated with the values specified in the data array.
            </p>
<p>
                If you provide an array of strings as the third argument, these
                strings are joined together as terms in an expression separated
                by <code class="code">AND</code> operators.
            </p>
<div class="example">
<a name="zend.db.adapter.write.update.example-array"></a><p class="title"><b>Example 10.22. Updating rows using an array of expressions</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$data = array(
    'updated_on'      =&gt; '2007-03-23',
    'bug_status'      =&gt; 'FIXED'
);

$where[] = "reported_by = 'goofy'";
$where[] = "bug_status = 'OPEN'";

$n = $db-&gt;update('bugs', $data, $where);

// Resulting SQL is:
//  UPDATE "bugs" SET "update_on" = '2007-03-23', "bug_status" = 'FIXED'
//  WHERE ("reported_by" = 'goofy') AND ("bug_status" = 'OPEN')
                </pre></div>
</div>
<br class="example-break">
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.write.delete"></a>10.1.4.4. Deleting Data</h4></div></div></div>
<p>
                You can delete rows from a database table using the
                <code class="code">delete()</code> method.  This method takes two arguments:
                the first is a string naming the table.
            </p>
<p>
                The second argument is a string containing an SQL expression
                that is used as criteria for the rows to delete.  The values
                and identifiers in this argument are not quoted or escaped.
                You are responsible for ensuring that any dynamic content is
                interpolated into this string safely.
                See <a href="zend.db.html#zend.db.adapter.quoting" title="10.1.5. Quoting Values and Identifiers">Section 10.1.5, “Quoting Values and Identifiers”</a>
                for methods to help you do this.
            </p>
<p>
                The return value is the number of rows affected by the delete
                operation.
            </p>
<div class="example">
<a name="zend.db.adapter.write.delete.example"></a><p class="title"><b>Example 10.23. Deleting rows</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$n = $db-&gt;delete('bugs', 'bug_id = 3');
                </pre></div>
</div>
<br class="example-break"><p>
                If you omit the second argument, the result is that all rows in
                the database table are deleted.
            </p>
<p>
                If you provide an array of strings as the second argument, these
                strings are joined together as terms in an expression separated
                by <code class="code">AND</code> operators.
            </p>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="zend.db.adapter.quoting"></a>10.1.5. Quoting Values and Identifiers</h3></div></div></div>
<p>
            When you form SQL queries, often it is the case that you need to
            include the values of PHP variables in SQL expressions.  This is
            risky, because if the value in a PHP string contains certain
            symbols, such as the quote symbol, it could result in invalid SQL.
            For example, notice the imbalanced quote characters in the
            following query:
            </p>
<pre class="programlisting">
$name = "O'Reilly";
$sql = "SELECT * FROM bugs WHERE reported_by = '$name'";

echo $sql;
// SELECT * FROM bugs WHERE reported_by = 'O'Reilly'
            </pre>
<p>
        </p>
<p>
            Even worse is the risk that such code mistakes might be exploited
            deliberately by a person who is trying to manipulate the function
            of your web application.  If they can specify the value of a PHP
            variable through the use of an HTTP parameter or other mechanism,
            they might be able to make your SQL queries do things that you
            didn't intend them to do, such as return data to which the person
            should not have privilege to read.  This is a serious and widespread
            technique for violating application security, known as "SQL Injection"
            (see <a href="http://en.wikipedia.org/wiki/SQL_Injection" target="_top">http://en.wikipedia.org/wiki/SQL_Injection</a>).
        </p>
<p>
            The Zend_Db Adapter class provides convenient functions to help you
            reduce vulnerabilities to SQL Injection attacks in your PHP code.
            The solution is to escape special characters such as quotes in PHP
            values before they are interpolated into your SQL strings.
            This protects against both accidental and deliberate manipulation
            of SQL strings by PHP variables that contain special characters.
        </p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.quoting.quote"></a>10.1.5.1. Using <code class="code">quote()</code>
</h4></div></div></div>
<p>
                The <code class="code">quote()</code> method accepts a single argument, a
                scalar string value.  It returns the value with special
                characters escaped in a manner appropriate for the RDBMS you
                are using, and surrounded by string value delimiters.  The
                standard SQL string value delimiter is the single-quote
                (<code class="code">'</code>).
            </p>
<div class="example">
<a name="zend.db.adapter.quoting.quote.example"></a><p class="title"><b>Example 10.24. Using quote()</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$name = $db-&gt;quote("O'Reilly");
echo $name;
// 'O\'Reilly'

$sql = "SELECT * FROM bugs WHERE reported_by = $name";

echo $sql;
// SELECT * FROM bugs WHERE reported_by = 'O\'Reilly'
                </pre></div>
</div>
<br class="example-break"><p>
                Note that the return value of <code class="code">quote()</code> includes the
                quote delimiters around the string.  This is different from
                some functions that escape special characters but do not add
                the quote delimiters, for example
                <a href="http://www.php.net/mysqli_real_escape_string" target="_top">mysql_real_escape_string()</a>.
            </p>
<p>
                Values may need to be quoted or not quoted according to the SQL
                datatype context in which they are used.  For instance, in some
                RDBMS brands, an integer value must not be quoted as a string
                if it is compared to an integer-type column or expression.
                In other words, the following is an error in some SQL
                implementations, assuming <code class="code">intColumn</code> has a SQL
                datatype of <code class="code">INTEGER</code>

                </p>
<pre class="programlisting">
SELECT * FROM atable WHERE intColumn = '123'
                </pre>
<p>
            </p>
<p>
                You can use the optional second argument to the
                <code class="code">quote()</code> method to apply quoting selectively for
                the SQL datatype you specify.
            </p>
<div class="example">
<a name="zend.db.adapter.quoting.quote.example-2"></a><p class="title"><b>Example 10.25. Using quote() with a SQL type</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$value = '1234';
$sql = 'SELECT * FROM atable WHERE intColumn = '
     . $db-&gt;quote($value, 'INTEGER');

                </pre></div>
</div>
<br class="example-break"><p>
                Each Zend_Db_Adapter class has encoded the names of numeric
                SQL datatypes for the respective brand of RDBMS.  You can also
                use the constants <code class="code">Zend_Db::INT_TYPE</code>,
                <code class="code">Zend_Db::BIGINT_TYPE</code>, and
                <code class="code">Zend_Db::FLOAT_TYPE</code> to write code in a more
                RDBMS-independent way.
            </p>
<p>
                Zend_Db_Table specifies SQL types to <code class="code">quote()</code>
                automatically when generating SQL queries that reference a
                table's key columns.
            </p>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.quoting.quote-into"></a>10.1.5.2. Using <code class="code">quoteInto()</code>
</h4></div></div></div>
<p>
                The most typical usage of quoting is to interpolate a PHP
                variable into a SQL expression or statement.  You can use the
                <code class="code">quoteInto()</code> method to do this in one step.  This
                method takes two arguments: the first argument is a string
                containing a placeholder symbol (<code class="code">?</code>), and the
                second argument is a value or PHP variable that should be
                substituted for that placeholder.
            </p>
<p>
                The placeholder symbol is the same symbol used by many RDBMS
                brands for positional parameters, but the
                <code class="code">quoteInto()</code> method only emulates query parameters.
                The method simply interpolates the value into the string,
                escapes special characters, and applies quotes around it.
                True query parameters maintain the separation between the SQL
                string and the parameters as the statement is parsed in the
                RDBMS server.
            </p>
<div class="example">
<a name="zend.db.adapter.quoting.quote-into.example"></a><p class="title"><b>Example 10.26. Using quoteInto()</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$sql = $db-&gt;quoteInto("SELECT * FROM bugs WHERE reported_by = ?", "O'Reilly");

echo $sql;
// SELECT * FROM bugs WHERE reported_by = 'O\'Reilly'
                </pre></div>
</div>
<br class="example-break"><p>
                You can use the optional third parameter of
                <code class="code">quoteInto()</code> to specify the SQL datatype.  Numeric
                datatypes are not quoted, and other types are quoted.
            </p>
<div class="example">
<a name="zend.db.adapter.quoting.quote-into.example-2"></a><p class="title"><b>Example 10.27. Using quoteInto() with a SQL type</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$sql = $db-&gt;quoteInto("SELECT * FROM bugs WHERE bug_id = ?", '1234', 'INTEGER');

echo $sql;
// SELECT * FROM bugs WHERE reported_by = 1234
                </pre></div>
</div>
<br class="example-break">
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.quoting.quote-identifier"></a>10.1.5.3. Using <code class="code">quoteIdentifier()</code>
</h4></div></div></div>
<p>
                Values are not the only part of SQL syntax that might need to
                be variable.  If you use PHP variables to name tables, columns,
                or other identifiers in your SQL statements, you might need to
                quote these strings too.  By default, SQL identifiers have
                syntax rules like PHP and most other programming languages.
                For example, identifiers should not contain spaces, certain
                punctuation or special characters, or international characters.
                Also certain words are reserved for SQL syntax, and should not
                be used as identifiers.
            </p>
<p>
                However, SQL has a feature called <span class="emphasis"><em>delimited identifiers</em></span>,
                which allows broader choices for the spelling of identifiers.
                If you enclose a SQL identifier in the proper types of quotes,
                you can use identifiers with spellings that would be invalid
                without the quotes.  Delimited identifiers can contain spaces,
                punctuation, or international characters.  You can also use SQL
                reserved words if you enclose them in identifier delimiters.
            </p>
<p>
                The <code class="code">quoteIdentifier()</code> method works like
                <code class="code">quote()</code>, but it applies the identifier delimiter
                characters to the string according to the type of Adapter you
                use.  For example, standard SQL uses double-quotes
                (<code class="code">"</code>) for identifier delimiters, and most RDBMS
                brands use that symbol.  MySQL uses back-quotes
                (<code class="code">`</code>) by default.  The
                <code class="code">quoteIdentifier()</code> method also escapes special
                characters within the string argument.
            </p>
<div class="example">
<a name="zend.db.adapter.quoting.quote-identifier.example"></a><p class="title"><b>Example 10.28. Using quoteIdentifier()</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
// we might have a table name that is an SQL reserved word
$tableName = $db-&gt;quoteIdentifier("order");

$sql = "SELECT * FROM $tableName";

echo $sql
// SELECT * FROM "order"
                </pre></div>
</div>
<br class="example-break"><p>
                SQL delimited identifiers are case-sensitive, unlike unquoted
                identifiers.  Therefore, if you use delimited identifiers, you
                must use the spelling of the identifier exactly as it is stored
                in your schema, including the case of the letters.
            </p>
<p>
                In most cases where SQL is generated within Zend_Db classes,
                the default is that all identifiers are delimited
                automatically.  You can change this behavior with the option
                <code class="code">Zend_Db::AUTO_QUOTE_IDENTIFIERS</code>.  Specify this
                when instantiating the Adapter.
                See <a href="zend.db.html#zend.db.adapter.connecting.parameters.example2" title="Example 10.6. Passing the auto-quoting option to the factory">Example 10.6, “Passing the auto-quoting option to the factory”</a>.
            </p>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="zend.db.adapter.transactions"></a>10.1.6. Controlling Database Transactions</h3></div></div></div>
<p>
            Databases define transactions as logical units of work that can be
            committed or rolled back as a single change, even if they operate
            on multiple tables.  All queries to a database are executed within
            the context of a transaction, even if the database driver manages
            them implicitly.  This is called <span class="emphasis"><em>auto-commit</em></span>
            mode, in which the database driver creates a transaction for every
            statement you execute, and commits that transaction after your
            SQL statement has been executed.  By default, all Zend_Db Adapter
            classes operate in auto-commit mode.
        </p>
<p>
            Alternatively, you can specify the beginning and resolution of a
            transaction, and thus control how many SQL queries are included in
            a single group that is committed (or rolled back) as a single
            operation.  Use the <code class="code">beginTransaction()</code> method to
            initiate a transaction.  Subsequent SQL statements are executed in
            the context of the same transaction until you resolve it
            explicitly.
        </p>
<p>
            To resolve the transaction, use either the <code class="code">commit()</code> or
            <code class="code">rollBack()</code> methods.  The <code class="code">commit()</code> method
            marks changes made during your transaction as committed, which
            means the effects of these changes are shown in queries run in
            other transactions.
        </p>
<p>
            The <code class="code">rollBack()</code> method does the opposite: it discards
            the changes made during your transaction.  The changes are
            effectively undone, and the state of the data returns to how it was
            before you began your transaction.  However, rolling back your
            transaction has no effect on changes made by other transactions
            running concurrently.
        </p>
<p>
            After you resolve this transaction, <code class="code">Zend_Db_Adapter</code>
            returns to auto-commit mode until you call
            <code class="code">beginTransaction()</code> again.
        </p>
<div class="example">
<a name="zend.db.adapter.transactions.example"></a><p class="title"><b>Example 10.29. Managing a transaction to ensure consistency</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
// Start a transaction explicitly.
$db-&gt;beginTransaction();

try {
    // Attempt to execute one or more queries:
    $db-&gt;query(...);
    $db-&gt;query(...);
    $db-&gt;query(...);

    // If all succeed, commit the transaction and all changes
    // are committed at once.
    $db-&gt;commit();

} catch (Exception $e) {
    // If any of the queries failed and threw an exception,
    // we want to roll back the whole transaction, reversing
    // changes made in the transaction, even those that succeeded.
    // Thus all changes are committed together, or none are.
    $db-&gt;rollBack();
    echo $e-&gt;getMessage();
}
            </pre></div>
</div>
<br class="example-break">
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="zend.db.adapter.list-describe"></a>10.1.7. Listing and Describing Tables</h3></div></div></div>
<p>
            The <code class="code">listTables()</code> method returns an array of strings,
            naming all tables in the current database.
        </p>
<p>
            The <code class="code">describeTable()</code> method returns an associative
            array of metadata about a table.  Specify the name of the table
            as a string in the first argument to this method.  The second
            argument is optional, and names the schema in which the table
            exists.
        </p>
<p>
            The keys of the associative array returned are the column names of
            the table.  The value corresponding to each column is also an
            associative array, with the following keys and values:
        </p>
<div class="table">
<a name="zend.db.adapter.list-describe.metadata"></a><p class="title"><b>Table 10.1. Metadata fields returned by describeTable()</b></p>
<div class="table-contents"><table summary="Metadata fields returned by describeTable()" border="1">
<colgroup>
<col>
<col>
<col>
</colgroup>
<thead><tr>
<th align="left">Key</th>
<th align="left">Type</th>
<th align="left">Description</th>
</tr></thead>
<tbody>
<tr>
<td align="left">SCHEMA_NAME</td>
<td align="left">(string)</td>
<td align="left">Name of the database schema in which this table exists.</td>
</tr>
<tr>
<td align="left">TABLE_NAME</td>
<td align="left">(string)</td>
<td align="left">Name of the table to which this column belongs.</td>
</tr>
<tr>
<td align="left">COLUMN_NAME</td>
<td align="left">(string)</td>
<td align="left">Name of the column.</td>
</tr>
<tr>
<td align="left">COLUMN_POSITION</td>
<td align="left">(integer)</td>
<td align="left">Ordinal position of the column in the table.</td>
</tr>
<tr>
<td align="left">DATA_TYPE</td>
<td align="left">(string)</td>
<td align="left">RDBMS name of the datatype of the column.</td>
</tr>
<tr>
<td align="left">DEFAULT</td>
<td align="left">(string)</td>
<td align="left">Default value for the column, if any.</td>
</tr>
<tr>
<td align="left">NULLABLE</td>
<td align="left">(boolean)</td>
<td align="left">True if the column accepts SQL NULLs, false if the column has a NOT NULL constraint.</td>
</tr>
<tr>
<td align="left">LENGTH</td>
<td align="left">(integer)</td>
<td align="left">Length or size of the column as reported by the RDBMS.</td>
</tr>
<tr>
<td align="left">SCALE</td>
<td align="left">(integer)</td>
<td align="left">Scale of SQL NUMERIC or DECIMAL type.</td>
</tr>
<tr>
<td align="left">PRECISION</td>
<td align="left">(integer)</td>
<td align="left">Precision of SQL NUMERIC or DECIMAL type.</td>
</tr>
<tr>
<td align="left">UNSIGNED</td>
<td align="left">(boolean)</td>
<td align="left">True if an integer-based type is reported as UNSIGNED.</td>
</tr>
<tr>
<td align="left">PRIMARY</td>
<td align="left">(boolean)</td>
<td align="left">True if the column is part of the primary key of this table.</td>
</tr>
<tr>
<td align="left">PRIMARY_POSITION</td>
<td align="left">(integer)</td>
<td align="left">Ordinal position (1-based) of the column in the primary key.</td>
</tr>
<tr>
<td align="left">IDENTITY</td>
<td align="left">(boolean)</td>
<td align="left">True if the column uses an auto-generated value.</td>
</tr>
</tbody>
</table></div>
</div>
<br class="table-break"><div class="note"><table border="0" summary="Note: How the IDENTITY metadata field relates to specific RDBMS">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td>
<th align="left">How the IDENTITY metadata field relates to specific RDBMS</th>
</tr>
<tr><td align="left" valign="top">
<p>
                The IDENTITY metadata field was chosen as an 'idiomatic' term to
                represent a relation to surrogate keys. This field can be
                commonly known by the following values:-
            </p>
<div class="itemizedlist"><ul type="disc">
<li><p>
                        <code class="code">IDENTITY</code> - DB2, MSSQL
                    </p></li>
<li><p>
                        <code class="code">AUTO_INCREMENT</code> - MySQL
                    </p></li>
<li><p>
                        <code class="code">SERIAL</code> - PostgreSQL
                    </p></li>
<li><p>
                        <code class="code">SEQUENCE</code> - Oracle
                    </p></li>
</ul></div>
</td></tr>
</table></div>
<p>
            If no table exists matching the table name and optional schema name
            specified, then <code class="code">describeTable()</code> returns an empty array.
        </p>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="zend.db.adapter.closing"></a>10.1.8. Closing a Connection</h3></div></div></div>
<p>
            Normally it is not necessary to close a database connection.  PHP
            automatically cleans up all resources and the end of a request.
            Database extensions are designed to close the connection as the
            reference to the resource object is cleaned up.
        </p>
<p>
            However, if you have a long-duration PHP script that initiates many
            database connections, you might need to close the connection, to avoid
            exhausting the capacity of your RDBMS server.  You can use the
            Adapter's <code class="code">closeConnection()</code> method to explicitly close
            the underlying database connection.
        </p>
<div class="example">
<a name="zend.db.adapter.closing.example"></a><p class="title"><b>Example 10.30. Closing a database connection</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$db-&gt;closeConnection();
            </pre></div>
</div>
<br class="example-break"><div class="note"><table border="0" summary="Note: Does Zend_Db support persistent connections?">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td>
<th align="left">Does Zend_Db support persistent connections?</th>
</tr>
<tr><td align="left" valign="top">
<p>
                The usage of persistent connections is not supported
                or encouraged in Zend_Db.
            </p>
<p>
                Using persistent connections can cause an excess of idle
                connections on the RDBMS server, which causes more problems
                than any performance gain you might achieve by reducing the
                overhead of making connections.
            </p>
<p>
                Database connections have state.  That is, some objects in the
                RDBMS server exist in session scope.  Examples are locks, user
                variables, temporary tables, and information about the most
                recently executed query, such as rows affected, and last
                generated id value.  If you use persistent connections, your
                application could access invalid or privileged data that were
                created in a previous PHP request.
            </p>
</td></tr>
</table></div>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="zend.db.adapter.other-statements"></a>10.1.9. Running Other Database Statements</h3></div></div></div>
<p>
            There might be cases in which you need to access the connection
            object directly, as provided by the PHP database extension.  Some
            of these extensions may offer features that are not surfaced by
            methods of Zend_Db_Adapter_Abstract.
        </p>
<p>
            For example, all SQL statements run by Zend_Db are prepared, then
            executed.  However, some database features are incompatible with
            prepared statements.  DDL statements like CREATE and ALTER cannot
            be prepared in MySQL.  Also, SQL statements don't benefit
            from the <a href="http://dev.mysql.com/doc/refman/5.1/en/query-cache-how.html" target="_top">MySQL Query Cache</a>,
            prior to MySQL 5.1.17.
        </p>
<p>
            Most PHP database extensions provide a method to execute SQL
            statements without preparing them.  For example, in PDO, this
            method is <code class="code">exec()</code>.  You can access the connection
            object in the PHP extension directly using getConnection().
        </p>
<div class="example">
<a name="zend.db.adapter.other-statements.example"></a><p class="title"><b>Example 10.31. Running a non-prepared statement in a PDO adapter</b></p>
<div class="example-contents"><pre class="programlisting">&lt;?php
$result = $db-&gt;getConnection()-&gt;exec('DROP TABLE bugs');
            </pre></div>
</div>
<br class="example-break"><p>
            Similarly, you can access other methods or properties that are
            specific to PHP database extensions.  Be aware, though, that by
            doing this you might constrain your application to the interface
            provided by the extension for a specific brand of RDBMS.
        </p>
<p>
            In future versions of Zend_Db, there will be opportunities to
            add method entry points for functionality that is common to
            the supported PHP database extensions.  This will not affect
            backward compatibility.
        </p>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="zend.db.adapter.adapter-notes"></a>10.1.10. Notes on Specific Adapters</h3></div></div></div>
<p>
            This section lists differences between the Adapter classes of which
            you should be aware.
        </p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.adapter-notes.ibm-db2"></a>10.1.10.1. IBM DB2</h4></div></div></div>
<div class="itemizedlist"><ul type="disc">
<li><p>
                        Specify this Adapter to the factory() method with the
                        name 'Db2'.
                    </p></li>
<li><p>
                        This Adapter uses the PHP extension ibm_db2.
                    </p></li>
<li><p>
                        IBM DB2 supports both sequences and auto-incrementing
                        keys.  Therefore the arguments to
                        <code class="code">lastInsertId()</code> are optional.  If you give
                        no arguments, the Adapter returns the last value
                        generated for an auto-increment key.  If you give
                        arguments, the Adapter returns the last value generated
                        by the sequence named according to the convention
                        '<span class="emphasis"><em>table</em></span>_<span class="emphasis"><em>column</em></span>_seq'.
                    </p></li>
</ul></div>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.adapter-notes.mysqli"></a>10.1.10.2. MySQLi</h4></div></div></div>
<div class="itemizedlist"><ul type="disc">
<li><p>
                        Specify this Adapter to the <code class="code">factory()</code>
                        method with the name 'Mysqli'.
                    </p></li>
<li><p>
                        This Adapter utilizes the PHP extension mysqli.
                    </p></li>
<li><p>
                        MySQL does not support sequences, so
                        <code class="code">lastInsertId()</code> ignores its arguments and
                        always returns the last value generated for an
                        auto-increment key.  The <code class="code">lastSequenceId()</code>
                        method returns <code class="code">null</code>.
                    </p></li>
</ul></div>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.adapter-notes.oracle"></a>10.1.10.3. Oracle</h4></div></div></div>
<div class="itemizedlist"><ul type="disc">
<li><p>
                        Specify this Adapter to the <code class="code">factory()</code>
                        method with the name 'Oracle'.
                    </p></li>
<li><p>
                        This Adapter uses the PHP extension oci8.
                    </p></li>
<li><p>
                        Oracle does not support auto-incrementing keys, so you
                        should specify the name of a sequence to
                        <code class="code">lastInsertId()</code> or
                        <code class="code">lastSequenceId()</code>.
                    </p></li>
<li><p>
                        The Oracle extension does not support positional
                        parameters.  You must use named parameters.
                    </p></li>
<li><p>
                        Currently the <code class="code">Zend_Db::CASE_FOLDING</code> option
                        is not supported by the Oracle adapter. To use this
                        option with Oracle, you must use the PDO OCI adapter.
                    </p></li>
</ul></div>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.adapter-notes.pdo-ibm"></a>10.1.10.4. PDO for IBM DB2 and Informix Dynamic Server (IDS)</h4></div></div></div>
<div class="itemizedlist"><ul type="disc">
<li><p>
                        Specify this Adapter to the <code class="code">factory()</code>
                        method with the name 'Pdo_Ibm'.
                    </p></li>
<li><p>
                        This Adapter uses the PHP extensions pdo and pdo_ibm.
                    </p></li>
<li><p>
                        You must use at least PDO_IBM extension version 1.2.2.
                        If you have an earlier version of this extension, you
                        must upgrade the PDO_IBM extension from PECL.
                    </p></li>
</ul></div>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.adapter-notes.pdo-mssql"></a>10.1.10.5. PDO Microsoft SQL Server</h4></div></div></div>
<div class="itemizedlist"><ul type="disc">
<li><p>
                        Specify this Adapter to the <code class="code">factory()</code>
                        method with the name 'Pdo_Mssql'.
                    </p></li>
<li><p>
                        This Adapter uses the PHP extensions pdo and pdo_mssql.
                    </p></li>
<li><p>
                        Microsoft SQL Server does not support sequences, so
                        <code class="code">lastInsertId()</code> ignores its arguments and
                        always returns the last value generated for an
                        auto-increment key.  The <code class="code">lastSequenceId()</code>
                        method returns <code class="code">null</code>.
                    </p></li>
<li><p>
                        Zend_Db_Adapter_Pdo_Mssql sets <code class="code">QUOTED_IDENTIFIER ON</code>
                        immediately after connecting to a SQL Server database.
                        This makes the driver use the standard SQL identifier
                        delimiter symbol (<code class="code">"</code>) instead of the
                        proprietary square-brackets syntax SQL Server uses for
                        delimiting identifiers.
                    </p></li>
<li><p>
                        You can specify <code class="code">pdoType</code> as a key in the
                        options array.  The value can be "mssql" (the default),
                        "dblib", "freetds", or "sybase".  This option affects
                        the DSN prefix the adapter uses when constructing the
                        DSN string.  Both "freetds" and "sybase" imply a prefix
                        of "sybase:", which is used for the
                        <a href="http://www.freetds.org/" target="_top">FreeTDS</a> set
                        of libraries.
                        See also
                        <a href="http://www.php.net/manual/en/ref.pdo-dblib.connection.php" target="_top">
                        http://www.php.net/manual/en/ref.pdo-dblib.connection.php</a>
                        for more information on the DSN prefixes used in this driver.
                    </p></li>
</ul></div>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.adapter-notes.pdo-mysql"></a>10.1.10.6. PDO MySQL</h4></div></div></div>
<div class="itemizedlist"><ul type="disc">
<li><p>
                        Specify this Adapter to the <code class="code">factory()</code>
                        method with the name 'Pdo_Mysql'.
                    </p></li>
<li><p>
                        This Adapter uses the PHP extensions pdo and pdo_mysql.
                    </p></li>
<li><p>
                        MySQL does not support sequences, so
                        <code class="code">lastInsertId()</code> ignores its arguments and
                        always returns the last value generated for an
                        auto-increment key.  The <code class="code">lastSequenceId()</code>
                        method returns <code class="code">null</code>.
                    </p></li>
</ul></div>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.adapter-notes.pdo-oci"></a>10.1.10.7. PDO Oracle</h4></div></div></div>
<div class="itemizedlist"><ul type="disc">
<li><p>
                        Specify this Adapter to the <code class="code">factory()</code>
                        method with the name 'Pdo_Oci'.
                    </p></li>
<li><p>
                        This Adapter uses the PHP extensions pdo and pdo_oci.
                    </p></li>
<li><p>
                        Oracle does not support auto-incrementing keys, so you
                        should specify the name of a sequence to
                        <code class="code">lastInsertId()</code> or
                        <code class="code">lastSequenceId()</code>.
                    </p></li>
</ul></div>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.adapter-notes.pdo-pgsql"></a>10.1.10.8. PDO PostgreSQL</h4></div></div></div>
<div class="itemizedlist"><ul type="disc">
<li><p>
                        Specify this Adapter to the <code class="code">factory()</code>
                        method with the name 'Pdo_Pgsql'.
                    </p></li>
<li><p>
                        This Adapter uses the PHP extensions pdo and pdo_pgsql.
                    </p></li>
<li><p>
                        PostgreSQL supports both sequences and auto-incrementing
                        keys.  Therefore the arguments to
                        <code class="code">lastInsertId()</code> are optional.  If you give
                        no arguments, the Adapter returns the last value
                        generated for an auto-increment key.  If you give
                        arguments, the Adapter returns the last value generated
                        by the sequence named according to the convention
                        '<span class="emphasis"><em>table</em></span>_<span class="emphasis"><em>column</em></span>_seq'.
                    </p></li>
</ul></div>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.adapter-notes.pdo-sqlite"></a>10.1.10.9. PDO SQLite</h4></div></div></div>
<div class="itemizedlist"><ul type="disc">
<li><p>
                        Specify this Adapter to the <code class="code">factory()</code>
                        method with the name 'Pdo_Sqlite'.
                    </p></li>
<li><p>
                        This Adapter uses the PHP extensions pdo and pdo_sqlite.
                    </p></li>
<li><p>
                        SQLite does not support sequences, so
                        <code class="code">lastInsertId()</code> ignores its arguments and
                        always returns the last value generated for an
                        auto-increment key.  The <code class="code">lastSequenceId()</code>
                        method returns <code class="code">null</code>.
                    </p></li>
<li><p>
                        To connect to an SQLite2 database, specify
                        <code class="code">'sqlite2'=&gt;true</code> in the array of
                        parameters when creating an instance of the
                        Pdo_Sqlite Adapter.
                    </p></li>
<li><p>
                        To connect to an in-memory SQLite database,
                        specify <code class="code">'dbname'=&gt;':memory:'</code> in the
                        array of parameters when creating an instance of
                        the Pdo_Sqlite Adapter.
                    </p></li>
<li><p>
                        Older versions of the SQLite driver for PHP do not seem
                        to support the PRAGMA commands necessary to ensure that
                        short column names are used in result sets.  If you
                        have problems that your result sets are returned with
                        keys of the form "tablename.columnname" when you do a
                        join query, then you should upgrade to the current
                        version of PHP.
                    </p></li>
</ul></div>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.db.adapter.adapter-notes.firebird"></a>10.1.10.10. Firebird/Interbase</h4></div></div></div>
<div class="itemizedlist"><ul type="disc">
<li><p>
                        This Adapter uses the PHP extension php_interbase.
                    </p></li>
<li><p>
                        Firebird/interbase does not support auto-incrementing keys,
                        so you should specify the name of a sequence to
                        <code class="code">lastInsertId()</code> or
                        <code class="code">lastSequenceId()</code>.
                    </p></li>
<li><p>
                        Currently the <code class="code">Zend_Db::CASE_FOLDING</code> option
                        is not supported by the Firebird/interbase adapter.
                        Unquoted identifiers are automatically returned in
                        upper case.
                    </p></li>
</ul></div>
</div>
</div>
</div>
</div>
<div class="navfooter"><table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left">
<a accesskey="p" href="zend.date.additional.html">Prev</a> </td>
<td width="20%" align="center"> </td>
<td width="40%" align="right"> <a accesskey="n" href="zend.db.statement.html">Next</a>
</td>
</tr>
<tr>
<td width="40%" align="left" valign="top">9.7. Working examples </td>
<td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td>
<td width="40%" align="right" valign="top"> 10.2. Zend_Db_Statement</td>
</tr>
</table></div>
<div class="revinfo"></div>
</body>
</html>
